#include <sourcemod>
#include <sdktools>
#include <l4d_stocks>
#include <l4d_weapon_stocks>
#include <sdkhooks>
#include "macros.sp"
#include "helpers.sp"

#define START_SOUND "ui/menu_countdown.wav"

new Handle:cvar_timetokeep_1 = INVALID_HANDLE;
new Handle:cvar_timetokeep_2 = INVALID_HANDLE;
new Handle:cvar_botblocktime_1 = INVALID_HANDLE;
new Handle:cvar_botblocktime_2 = INVALID_HANDLE;

new bool:surv_out = false;

#define NUMBEROFDOOR 5

#define UNLOCK 0
#define LOCK 1

new door_index[NUMBEROFDOOR] = { -1, ... };
new bool:no_door = true;

new time_left = 0;

public OnPluginStart()
{
	cvar_timetokeep_1 = CreateConVar("l4d2_norushstart_time_first", "70.0", "How many time before open the safe door room on first round");
	cvar_timetokeep_2 = CreateConVar("l4d2_norushstart_time_second", "40.0", "How many time before open the safe door room on second round");
	cvar_botblocktime_1 = CreateConVar("l4d2_RSBS_botblock_first", "70.0", "How many time a bot is blocked in safe room on first round", CVAR_FLAGS);
	cvar_botblocktime_2 = CreateConVar("l4d2_RSBS_botblock_second", "40.0", "How many time a bot is blocked in safe room on second round", CVAR_FLAGS);
	
	HookEvent("round_start", Event_round_start);
	HookEvent("round_end", Event_round_end);
	HookEvent("versus_round_start", event_versus_round_start);
}


public OnEntityCreated(entity, const String:classname[])
{
	if(strcmp(classname, "prop_door_rotating_checkpoint") == 0 )
	{
		SDKHook(entity, SDKHook_SpawnPost, OnDoorSpawn);
	}
}

public Action:OnDoorSpawn(ent)
{
	if((IsValidEntity(ent) || IsValidEdict(ent)))
	{
		new locked = GetEntProp(ent, Prop_Data, "m_bLocked");
		if(locked == 1) /* only safe room door */
		{
			new spawnflags = GetEntProp(ent, Prop_Send, "m_spawnflags");
			/* don't use the back door from blood harvest */
			if(spawnflags != 32768 && spawnflags != -32768)
			{
				ControlDoor(ent, LOCK);
				add_door(ent);
			}
		}
	}
}

clear_door()
{
	for(new i=0; i < NUMBEROFDOOR; i++)
	{
		door_index[i] = -1;
	}
	no_door = true;
}

add_door(ent)
{
	for(new i=0; i < NUMBEROFDOOR; i++)
	{
		if(door_index[i] == -1)
		{
			sub_debug("[DOOR] Adding %d", ent);
			no_door = false;
			door_index[i] = ent;
			return;
		}
	}
}


unlock_all_doors()
{
	for(new i=0; i < NUMBEROFDOOR; i++)
	{
		if(door_index[i] != -1)
		{
			ControlDoor(door_index[i], UNLOCK);			
		}
	}
}

public OnClientPutInServer(client)
{
	SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
}

public OnClientDisconnect(client)
{
	SDKUnhook(client, SDKHook_OnTakeDamage, OnTakeDamage);
}

public Action:OnTakeDamage(entity, &inflictor, &attacker, &Float:damage, &damageType, &weapon, const Float:damageForce[3], const Float:damagePosition[3])
{
	if(!surv_out)
	{
		if(IsValidSurvivor(entity) && IsValidSurvivor(inflictor))
		{
			damage = 0.0;
			return Plugin_Changed;
		}
	}

	return Plugin_Continue;
}

public OnMapStart()
{
	PrecacheSound(START_SOUND);
}

public OnMapEnd()
{
	clear_door();
}

public Action:Event_round_end(Handle:event, const String:name[], bool:dontBroadcast)
{
	clear_door();
}

public Action:Event_round_start(Handle:event, const String:name[], bool:dontBroadcast)
{

	SetConVarInt(FindConVar("sb_stop"), 1);
	surv_out = false;

	if(is_first_round()) //1st round
	{
		time_left = GetConVarInt(cvar_timetokeep_1);		
		CreateTimer(GetConVarFloat(cvar_botblocktime_1), unlockbot, _, TIMER_FLAG_NO_MAPCHANGE);
		CreateTimer(1.0, timer_tick, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
		
	}
	else //2nd round
	{	
		time_left = GetConVarInt(cvar_timetokeep_2);
		CreateTimer(GetConVarFloat(cvar_botblocktime_2), unlockbot, _, TIMER_FLAG_NO_MAPCHANGE);

		CreateTimer(1.0, timer_tick, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
	}

	SetConVarInt(FindConVar("versus_force_start_time"), time_left + 1);
}

public Action:event_versus_round_start(Handle:event, const String:name[], bool:dontBroadcast)
{
	SetConVarInt(FindConVar("sb_stop"), 0);
	PrintToChatAll("\x04Round started !\x01");
	EmitSoundToAll(START_SOUND);
	surv_out = true;
}


/*change a cvar to make bot active*/
public Action:unlockbot(Handle:timer, any:junk)
{
	SetConVarInt(FindConVar("sb_stop"), 0);
}

public Action:timer_tick(Handle:timer, any:junk)
{
	if(surv_out && no_door)
	{
		time_left = 0;
	}
	else
	{
		time_left--;
	}
	
	if(time_left > 0 && time_left % 10 == 0)
		PrintToChatAll("\x01Round start in \x03%d\x01 seconds\x01", time_left);

	if(time_left == 0)
	{
		unlock_all_doors();
		KillTimer(timer);
	}
}

ControlDoor(Entity, Operation)
{
	if(Operation == LOCK)
	{
		sub_debug("[DOOR] Locking %d", Entity);
		SetEntProp(Entity, Prop_Send, "m_spawnflags", 32768);
	}
	else if(Operation == UNLOCK)
	{
		sub_debug("[DOOR] Unlocking %d", Entity);
		SetEntProp(Entity, Prop_Send, "m_spawnflags", 2048);
	}
}
